﻿using System;
using System.Data;
using System.Configuration;

using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

using System.IO;
using System.Text;
using System.ComponentModel;
using System.Collections.Specialized;
using TA.JSON;
using System.Diagnostics;
using TA.Win.Utils.Design;
using System.Drawing.Design;

namespace TA.Turbo.Controls
{
	/// <summary>
	/// Base control for all value display controls - controls that can output a value.
	/// </summary>
	public abstract class BaseValueDisplayControl : TControl
	{
		#region PUBLIC
		#region INIT
		/// <summary>
		/// Ctor.
		/// </summary>
		public BaseValueDisplayControl()
			: base(HtmlTextWriterTag.Input)
		{
			this.ViewState["Data"] = new FieldBinding();
		}
		#endregion
		#region PROPS
		#region DEF
		/// <summary>
		/// Props.
		/// </summary>
		protected static new Properties _clientProperties = Define(TControl._clientProperties,
			new BasePropertyDefinition[] {
				new JsonPropertyDefinition<FieldBinding>("Data", "D", null),
			});
		/// <summary>
		/// Props.
		/// </summary>
		public override Properties ClientProperties
		{
			get
			{
				return _clientProperties;
			}
		}
		#endregion
		/// <summary>
		/// Contains properties that control the way this value control is bound in data-binding scenarios.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		[Editor(typeof(PropertyEditor), typeof(UITypeEditor))]
		[Category("Data")]
		//[NotifyParentProperty(true)]
		//[PersistenceMode(PersistenceMode.InnerProperty)]
		public FieldBinding Data { get { return GetProperty<FieldBinding>("Data"); } }
		/// <summary>
		/// When implemented, gets or sets non-typed value.
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public abstract object GenericValue { get; set; }
		#endregion
		#endregion
		#region INTERNAL
		#region VARS
		FieldBinding _data = new FieldBinding();
		#endregion
		#region PROPS
		/// <summary>
		/// When implemented, gets or sets the serialized value - in the format that is suitable for client-server transfers.
		/// </summary>
		protected internal abstract string SerializedValue { get; set; }
		#endregion
		#region METHODS
		#region INIT
		protected internal override void RegisterIncludes(IncludeCollection includes)
		{
			base.RegisterIncludes(includes);

			// only includes FieldBinding if anything is bound
			// this way, reducing the amount of stuff included (which is a bit too much)
			//if (!string.IsNullOrEmpty(this.Data.Field))
			//if (this.TPage.OptionalScripts.Contains(Script.FieldBinding))
			//{
			//  includes.Add(Script.FieldBinding);
			//}

			includes.Add(Script.FieldBinding);
		}
		/// <summary>
		/// Loads the value for this control if the supplied control reference allows for it.
		/// </summary>
		/// <param name="cr"></param>
		/// <param name="nvc"></param>
		internal override void LoadState(BaseControlReference cr, NameValueCollection nvc)
		{
			base.LoadState(cr, nvc);

			if (cr.Value)
			{
				this.LoadStateValue(nvc);
			}
		}
		/// <summary>
		/// Loads the value for this control.
		/// </summary>
		/// <param name="nvc"></param>
		protected virtual void LoadStateValue(NameValueCollection nvc)
		{
			this.SerializedValue = nvc[this.UniqueID];
		}
		#endregion
		#region VALUE
		#endregion
		#region RENDER
		/// <summary>
		/// Calls the <see cref="AddValueAttributes"/> methods.
		/// </summary>
		/// <param name="writer"></param>
		protected override void AddAttributesToRender(HtmlTextWriter writer)
		{
			base.AddAttributesToRender(writer);

			this.AddValueAttributes(writer);
		}
		/// <summary>
		/// Appends attribute(s) for value.
		/// </summary>
		/// <param name="writer"></param>
		protected virtual void AddValueAttributes(HtmlTextWriter writer)
		{
			string v = this.SerializedValue;
			if (
				!string.IsNullOrEmpty(v) &&
				TControl.IsFormElementTag(this.TagString)
				&&
				(
					this.TPage == null
					|| 
					this.TPage.JavaScript != false
				)
			)
			{
				writer.AddAttribute(HtmlTextWriterAttribute.Value, v);
			}
		}
		/// <summary>
		/// Outputs the needed part of the state of this control to the specified <see cref="JsonWriter"/>.
		/// </summary>
		/// <param name="jw"></param>
		/// <param name="cr"></param>
		internal override void SaveStateContents(TA.JSON.JsonWriter jw, BaseControlReference cr)
		{
			base.SaveStateContents(jw, cr);

			if (cr.Value)
			{
				jw.PropertyName("V");
				SaveValue(jw);
			}
		}
		/// <summary>
		/// Outputs the value of this control to the specified <see cref="JsonWriter"/>.
		/// </summary>
		/// <param name="jw"></param>
		protected virtual void SaveValue(JsonWriter jw)
		{
			jw.Value(this.SerializedValue);
		}
		#endregion
		#endregion
		#endregion
	}
}